package Singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * @Author: 蔡翔
 * @Date: 2019/11/18 16:12
 * @Version 1.0
 */
public class LazySingleton {
    //这里 ，系统刚启动的时候是不加载的。
    private static LazySingleton lazySingleton = null;

    // 如果为true就代表这个类还能进行实例，否则就会抛出异常。
    private static boolean flag = true;

    private LazySingleton(){
        if(flag){
            flag = false;
        }else {
            throw new RuntimeException("单例构造器 禁止反射调用");
        }
    }
    public synchronized static LazySingleton getInstance(){
        if(lazySingleton ==null){
            //这里就是延迟加载的核心，只有在用它的时候才加载
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        Class objecClass = LazySingleton.class;
        Constructor constructor = objecClass.getDeclaredConstructor();
        // 这一条代码修改了 构造器的private权限
        constructor.setAccessible(true);

        LazySingleton o1 = LazySingleton.getInstance();
        //通过反射把 LazySingleton 里面的flag改为true;
        Field flag = o1.getClass().getDeclaredField("flag");
        flag.setAccessible(true);
        flag.set(o1,true);

        LazySingleton o2 = (LazySingleton) constructor.newInstance();

        System.out.println(o1);
        System.out.println(o2);
        System.out.println(o1 == o2);
    }
}
